package mirfordevoservice.system.service.Handler;

/**
 * Created by Heart!
 *
 * @Author ZhangChaoJian
 * @Date 2018/3/26.18:24
 * Wants More Then Try Hard More!
 */

import mirfordevoservice.system.req.inter_face.ReqMessage;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static mirfordevoservice.system.contasnt.GameConstant.CacheCenter.PROTOCOL_CONFIG_CACHE;

/**
 * 消息处理工具
 */
public class ReqHandler {
    private static ReqHandler INSTANCE = new ReqHandler();
    private ReentrantLock lock = new ReentrantLock();

    private ReqHandler() {
    }

    public static ReqHandler getINSTANCE() {
        return INSTANCE;
    }

    /**
     * 心跳逻辑
     *
     * @param in
     * @param out
     * @param client
     */
    public void isHeartBeat(ObjectInputStream in, ObjectOutputStream out, Socket client) throws IOException, ClassNotFoundException {
        Object msg = in.readObject();
        String msgFromClient = null;
        if (msg instanceof Integer) { //检测客户端是否发送心跳包
            setAlive();
            return;
        }
        if (msg instanceof String) {
            msgFromClient = (String) msg;
        }
        if (msgFromClient == null) {
            try {
                client.sendUrgentData(0);
            } catch (IOException e) {
                System.out.println("远程主机被迫关闭一个现有链接");
                System.out.println(client.getLocalAddress() + "\t" + client.getLocalPort());
                try {
                    client.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                System.out.println("执行客户端断线逻辑...");
            }
        } else {
            readMsgFromClient(msgFromClient, in, out, client);
        }

    }

    /**
     * 服务端上次心跳时间
     */
    public static long lastTime = System.currentTimeMillis();

    /**
     * 服务端存活检测
     */
    private void setAlive() {
        lastTime = System.currentTimeMillis();
    }

    /**
     * 处理正常事务
     *
     * @param msgFromClient
     * @param in
     * @param out
     * @param client
     */
    private void readMsgFromClient(String msgFromClient, ObjectInputStream in, ObjectOutputStream out, Socket client) {
        if (!PROTOCOL_CONFIG_CACHE.containsKey(msgFromClient)) {
            System.err.println("无效请求...");
            return;
        }
        Class clazz = PROTOCOL_CONFIG_CACHE.get(msgFromClient);
        ReqMessage reqMessage = null;
        try {
            reqMessage = (ReqMessage) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (reqMessage == null) {
            System.err.println("找不到协议配置");
            return;
        }
        /**
         * 执行业务逻辑
         */
        lock.lock();//上锁
        /**
         * 刷新输出流
         */
        try {
            out.reset();
        } catch (IOException e) {
            e.printStackTrace();
        }
        reqMessage.receiveAndSend(in, out, client);
        reqMessage.receive(in, client);
        reqMessage.sendMsg(out);
        lock.unlock();//解锁
    }
}
